package dnbW.entityW;

import dnbW.dbW.DataSource;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author truongbaquan
 */
public class Entity implements IEntity {
    // <editor-fold defaultstate="collapsed" desc="Decorator Pattern">
    private IPath path;

    @Override
    public IPath getPath() {
        return path;
    }

    @Override
    public DataSource getDataSource() {
        return this.path.getDataSource();
    }

    @Override
    public String[] getElements() {
        return this.path.getElements();
    }

    @Override
    public String getElementAtLevel(int level) {
        return this.path.getElementAtLevel(level);
    }

    @Override
    public boolean isAttribute() {
        return this.path.isAttribute();
    }

    @Override
    public int getLevel() {
        return this.path.getLevel();
    }

    @Override
    public String toSQLPathExp() {
        return this.path.toSQLPathExp();
    }

    @Override
    public String toPathExp() {
        return this.path.toPathExp();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Relationships">
    private HashMap<IEntity, Relationship> relationships = new HashMap<IEntity, Relationship>();

    @Override
    public Relationship getRelationship(IEntity other) {
        return this.relationships.get(other);
    }

    @Override
    public Collection<Relationship> getRelationships() {
        return this.relationships.values();
    }

    @Override
    public Cardinality getCardinality(Relationship relationship) {
        if (this.equals(relationship.getEntity1())) return relationship.getCardinality1();
        else if (this.equals(relationship.getEntity2())) return relationship.getCardinality2();
        else return Cardinality.unknown;
    }

    @Override
    public void addRelationship(IEntity other, Relationship relationship) {
        this.relationships.put(other, relationship);
    }

    @Override
    public Set<IEntity> getRelatedEntities() {
        return this.relationships.keySet();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Attributes">
    private Set<Attribute> attributes = new TreeSet<Attribute>(new AttributeFrequencyComparator());
    
    @Override
    public Collection<Attribute> getAttributes() {
        return this.attributes;
    }
    
    @Override
    public void addAttribute(Attribute attribute) {
        this.attributes.add(attribute);
    }
    // </editor-fold>

    public Entity(IPath path) {
        this.path = path;
    }
    
    @Override
    public String toString() {
        return this.path.toPathExp();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Entity other = (Entity) obj;
        if (this.path != other.path && (this.path == null || !this.path.equals(other.path))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 19 * hash + (this.path != null ? this.path.hashCode() : 0);
        return hash;
    }
}
